package com.shungen.apicloud.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.shungen.apicloud.annotation.AuthCheck;
import com.shungen.apicloud.common.BaseResponse;
import com.shungen.apicloud.common.ErrorCode;
import com.shungen.apicloud.common.ResultUtils;
import com.shungen.apicloud.exception.BusinessException;
import com.shungen.apicloud.exception.ThrowUtils;
import com.shungen.apicloud.model.dto.interfaceaction.InterfaceInvokeActionRequest;
import com.shungen.apicloud.model.entity.InterfaceInfo;
import com.shungen.apicloud.model.entity.User;
import com.shungen.apicloud.service.InterfaceInfoService;
import com.shungen.apicloud.service.UserService;
import com.shungen.apicloud.utils.JWTUtil;
import com.shungen.apicloud.utils.SignUtils;
import com.shungen.apicloud.utils.UrlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author shungen
 * @date 2024年08月08日 9:17
 */
@RestController
@RequestMapping("/interface")
@Slf4j
public class InterfaceActionController {

    @Resource
    private InterfaceInfoService interfaceInfoService;


    @Resource
    private UserService userService;


    @PostMapping("/invoke")
    @AuthCheck
    public String interfaceInvoke(@RequestBody InterfaceInvokeActionRequest interfaceInvokeActionRequest, HttpServletRequest httpServletRequest) {

        String token = httpServletRequest.getHeader("token");
        Long userId = Long.valueOf(JWTUtil.getClaimFromToken(token, "id"));
        User loginUser = userService.getById(userId);
        String accessKey = loginUser.getAccessKey();
        String secretKey = loginUser.getSecretKey();


        ThrowUtils.throwIf(interfaceInvokeActionRequest == null, ErrorCode.PARAMS_ERROR, "请求参数错误");

        Long interfaceId = interfaceInvokeActionRequest.getInterfaceId();
        ThrowUtils.throwIf(interfaceId == null, ErrorCode.PARAMS_ERROR, "接口id参数缺失");

        InterfaceInfo interfaceInfo = interfaceInfoService.getById(interfaceId);
        ThrowUtils.throwIf(interfaceInfo == null, ErrorCode.PARAMS_ERROR, "接口信息不存在");
        ThrowUtils.throwIf(!interfaceInfo.getMethod().equalsIgnoreCase(interfaceInvokeActionRequest.getMethod()), ErrorCode.PARAMS_ERROR, "请求方法错误");


        log.info("在线接口调用收到前端传来的数据: {}", JSONUtil.toJsonStr(interfaceInvokeActionRequest));

        // 分装请求，发送请求
        String method = interfaceInvokeActionRequest.getMethod().toLowerCase();
//        String url = interfaceInvokeActionRequest.getUrl();
        String url = null;
        try {
            url = "localhost:9900/openapi" + UrlUtils.extractUri(interfaceInfo.getUrl());
        } catch (URISyntaxException e) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"接口url为空");
        }
        HttpRequest request;

        switch (method) {
            case "get":
                request = HttpRequest.get(url);
                break;
            case "post":
                request = HttpRequest.post(url);
                break;
            case "put":
                request = HttpRequest.put(url);
                break;
            case "delete":
                request = HttpRequest.delete(url);
                break;
            default:
                throw new IllegalArgumentException("Unsupported method: " + method);
        }

        // 添加请求头
        if (interfaceInvokeActionRequest.getHeaders() != null && !interfaceInvokeActionRequest.getHeaders().isEmpty()) {
            interfaceInvokeActionRequest.getHeaders().forEach(request::header);
        }
        request.header("interfaceId",String.valueOf(interfaceId));

        // 添加请求参数
        if (interfaceInvokeActionRequest.getQueryParams() != null && !interfaceInvokeActionRequest.getQueryParams().isEmpty()) {
            interfaceInvokeActionRequest.getQueryParams().forEach(request::form);
        }


        // 添加请求体
        if (interfaceInvokeActionRequest.getRequestBody() != null && !interfaceInvokeActionRequest.getRequestBody().isEmpty() ) {//&& !"get".equals(method)我的get请求里面也带了请求体
            request.body(JSONUtil.toJsonStr(interfaceInvokeActionRequest.getRequestBody()));
        }

        // TODO: 在线调用部分，处理文件参数


        //获取完请求头之后，进行签名
        // 准备用于签名的数据
        String nonce = RandomUtil.randomNumbers(4);
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String signData = nonce + timestamp;


        // 生成签名
        String signature = SignUtils.generateSignature(signData,secretKey);

        // 将签名、随机数、时间戳和accessKey添加到请求头
        request.header("accessKey", accessKey);
        request.header("nonce", nonce);
        request.header("timestamp", timestamp);
        request.header("signature", signature);




        HttpResponse response;
        try {
            response = request.execute();
        } catch (Exception e) {
            log.error("接口调用异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "接口调用异常");
        }

        log.info("接口调用响应: {}", response.body());

        return response.body();
    }




//    @PostMapping("/invoke")
//    public String interfaceInvoke(@RequestBody InterfaceInvokeActionRequest interfaceInvokeActionRequest) {
//        ThrowUtils.throwIf(interfaceInvokeActionRequest == null, ErrorCode.PARAMS_ERROR, "请求参数错误");
//
//        Long interfaceId = interfaceInvokeActionRequest.getInterfaceId();
//        ThrowUtils.throwIf(interfaceId == null, ErrorCode.PARAMS_ERROR, "接口id参数缺失");
//
//        InterfaceInfo interfaceInfo = interfaceInfoService.getById(interfaceId);
//        ThrowUtils.throwIf(interfaceInfo == null, ErrorCode.PARAMS_ERROR, "接口信息不存在");
//        ThrowUtils.throwIf(!interfaceInfo.getMethod().equalsIgnoreCase(interfaceInvokeActionRequest.getMethod()), ErrorCode.PARAMS_ERROR, "请求方法错误");
//
//
//        log.info("在线接口调用收到前端传来的数据: {}", JSONUtil.toJsonStr(interfaceInvokeActionRequest));
//
//        // 分装请求，发送请求
//        String method = interfaceInvokeActionRequest.getMethod().toLowerCase();
//        String url = interfaceInvokeActionRequest.getUrl();
//        HttpRequest request;
//
//        switch (method) {
//            case "get":
//                request = HttpRequest.get(url);
//                break;
//            case "post":
//                request = HttpRequest.post(url);
//                break;
//            case "put":
//                request = HttpRequest.put(url);
//                break;
//            case "delete":
//                request = HttpRequest.delete(url);
//                break;
//            default:
//                throw new IllegalArgumentException("Unsupported method: " + method);
//        }
//
//        // 添加请求头
//        if (interfaceInvokeActionRequest.getHeaders() != null && !interfaceInvokeActionRequest.getHeaders().isEmpty()) {
//            interfaceInvokeActionRequest.getHeaders().forEach(request::header);
//        }
//
//        // 添加请求参数
//        if (interfaceInvokeActionRequest.getQueryParams() != null && !interfaceInvokeActionRequest.getQueryParams().isEmpty()) {
//            interfaceInvokeActionRequest.getQueryParams().forEach(request::form);
//        }
//
//        // 添加请求体
//        if (interfaceInvokeActionRequest.getRequestBody() != null && !interfaceInvokeActionRequest.getRequestBody().isEmpty() ) {//&& !"get".equals(method)我的get请求里面也带了请求体
//            request.body(JSONUtil.toJsonStr(interfaceInvokeActionRequest.getRequestBody()));
//        }
//
//        // TODO: 在线调用部分，处理文件参数
//
//
//        HttpResponse response;
//        try {
//            response = request.execute();
//        } catch (Exception e) {
//            log.error("接口调用异常", e);
//            throw new BusinessException(ErrorCode.OPERATION_ERROR, "接口调用异常");
//        }
//
//        log.info("接口调用响应: {}", response.body());
//
//        return response.body();
//    }
}